//
//  AsyncService.m
//  VinSwiper
//
//  Created by siloon on 5/17/11.
//  Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "SLAsyncService.h"

@implementation SLAsyncService

@synthesize debugLogEnabled = _debugLogEnabled;

@synthesize isWorking = _isWorking;
@synthesize requestQueue = _requestQueue;
@synthesize callbackQueue = _callbackQueue;

#pragma mark -

- (NSOperationQueue *)createRequestQueue{
	NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
	[queue setMaxConcurrentOperationCount:1];
	return queue;
}

- (BOOL)isWorking{
	NSUInteger count = [self.requestQueue operationCount];
	for(NSOperation *opr in self.requestQueue.operations){
		if([opr isCancelled]){
			count --;
		}
	}
	return count > 0;
}

#pragma mark -

- (id)init {
    self = [super init];
    if (self) {
		self.requestQueue = [self createRequestQueue];
		
		self.callbackQueue = [[[SLQueue alloc] init] autorelease];
		
    }
    return self;
}

- (void)dealloc {
	self.requestQueue = nil;
	self.callbackQueue = nil;
    [super dealloc];
}

#pragma mark -

- (void)notifiyErrorThenEndRequest:(NSError *)error{
	SLCallback *callback = [self.callbackQueue peekLast];
	[callback.target performSelectorOnMainThread:callback.selector withObject:error waitUntilDone:YES];
	[self setRequestEndStatus];
}

- (void)notifiyFinishedThenEndRequest:(id)data{
	SLCallback *callback = [self.callbackQueue peekLast];
	[callback.target performSelectorOnMainThread:callback.selector withObject:data waitUntilDone:YES];
	[self setRequestEndStatus];
}

- (void)setRequestStartStatus{
	[self.callbackQueue clearQueue];
}

- (void)setRequestEndStatus{
	[self.requestQueue cancelAllOperations];
	self.requestQueue = [self createRequestQueue];
	[self.callbackQueue clearQueue];
}


#pragma mark -

- (void)request:(SLAsyncRequest *)request didFailWithError:(NSError *)error{
	if([request isCancelled]){
		return;
	}
	[self notifiyErrorThenEndRequest:error];
}

- (void)request:(SLAsyncRequest *)request didFinishWithData:(id)data{
	if([request isCancelled]){
		return;
	}
	SLCallback *lastCallback = [self.callbackQueue peekLast];
	SLCallback *callback = [self.callbackQueue dequeue];
	[callback.target performSelectorOnMainThread:callback.selector withObject:data waitUntilDone:YES];
	
	if(callback == lastCallback){
		[self setRequestEndStatus];
	}
}


@end
